using System;
using System.Threading;


class TLSTest {
   [ThreadStaticAttribute]
   public static Int32 x = 5;
}



class App {


   // Define a System.Delegate-derived type called DisplayStringCallback.
   // An instance of this type identifies the address of a method that
   // takes a single String parameter and returns void.
   delegate Int32 DisplayStringCallback(String s);

   static void ProcessWorkItem(Object o) {
      Console.WriteLine("Processing WorkItem: {0}.", Thread.CurrentThread.GetHashCode());
      Console.WriteLine("x: {0}.", TLSTest.x);
      TLSTest.x = Thread.CurrentThread.GetHashCode();
      Console.WriteLine("x: {0}.", TLSTest.x);

      Thread.Sleep(5000);
      ((ManualResetEvent)o).Set();
   }


   static void EventGotSignaled(Object state, bool wasSignalled) {
      Console.WriteLine("In EventGotSignaled: {0}.", Thread.CurrentThread.GetHashCode());
      Console.WriteLine("wasSignalled: " + wasSignalled);
   }

   // Define the application's entry point method
   static void Main() {
      Console.WriteLine("Starting: {0}.", Thread.CurrentThread.GetHashCode());

      Console.WriteLine("x: {0}.", TLSTest.x);
      TLSTest.x = Thread.CurrentThread.GetHashCode();
      Console.WriteLine("x: {0}.", TLSTest.x);

#if NO
   //   Boolean ThreadPool.BindHandle(int osHandle);

      AutoResetEvent aevt = new AutoResetEvent(false);
      //new WaitOrTimerCallback(EventGotSignaled);
      Console.WriteLine("Before: {0}.", Thread.CurrentThread.GetHashCode());
      RegisteredWaitHandle rwh = ThreadPool.RegisterWaitForSingleObject(null, new WaitOrTimerCallback(EventGotSignaled), null, 2000, false);
      Console.WriteLine("After: {0}.", Thread.CurrentThread.GetHashCode());

      //ThreadPool.RegisterWaitForSingleObject(aevt, new WaitOrTimerCallback(EventGotSignaled), null, 2000, false);

      Thread.Sleep(3000);
      aevt.Set();
      aevt.Set();
      Thread.Sleep(10000);
#endif

      ManualResetEvent evt = new ManualResetEvent(false);
      Console.WriteLine("Starting: {0}.", Thread.CurrentThread.GetHashCode());
      ThreadPool.QueueUserWorkItem(new WaitCallback(ProcessWorkItem), evt);
      evt.WaitOne();

      Console.WriteLine("Exiting, x: {0}.", TLSTest.x);

      Console.WriteLine("Exiting: {0}.", Thread.CurrentThread.GetHashCode());
   }
}

